#include "SSP_College.hpp"
#include <stdexcept>
#include <thread>
#include <sstream>

using namespace std::chrono_literals;

SSPCollege::SSPCollege(const std::vector<std::pair<std::string,std::any>> & ipList,std::function<void(const char*,std::size_t size,unsigned long frameID,std::any & userData)> funcHandle)
{
  threadLooper.reset(new imf::ThreadLoop([&](imf::Loop *loop){
    for(auto & i : ipList)
      cameraObjectList.emplace_back(i.first,i.second,loop,funcHandle);
  }));
  threadLooper->start();
  std::this_thread::sleep_for(10s);
  StopShot();
  for(auto & i : cameraObjectList)
  {
    if(i.GetTestStatus()==false)
      throw std::runtime_error("相机启动自检失败");
  }
}

SSPCollege::~SSPCollege()
{
  threadLooper->stop();
}

void SSPCollege::StartShot()
{
  for(auto & i : cameraObjectList)
    i.StartShot();
}

void SSPCollege::StopShot()
{
  for(auto & i : cameraObjectList)
    i.StopShot();
}

SSPCollege::CameraObject::CameraObject(std::string ip_,std::any userData_,imf::Loop* loop,std::function<void(const char*,std::size_t size,unsigned long frameID,std::any & userData)> funcHandle_)
  : userData(userData_)
  , ip(ip_)
  , funcHandle(funcHandle_)
  , client(((std::stringstream())<<"http://"<<ip_).str())
{
  {
    auto res=client.Get("/ctrl/set?send_stream=Stream0");
    if(res==nullptr) throw std::runtime_error(((std::stringstream())<<"无法连接相机 ip:"<<ip_).str());
  }
  ssp_client=new imf::SspClient(ip_,loop,0x400000,9999,imf::STREAM_MAIN);
  ssp_client->init();
  ssp_client->setOnH264DataCallback(std::bind(&SSPCollege::CameraObject::on_264_callback,this,std::placeholders::_1));
  ssp_client->setOnMetaCallback(std::bind(&SSPCollege::CameraObject::on_meta_callback,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
  ssp_client->setOnAudioDataCallback(std::bind(&SSPCollege::CameraObject::on_audio_callback,this,std::placeholders::_1));
  ssp_client->setOnDisconnectedCallback(std::bind(&SSPCollege::CameraObject::on_disconnect_callback,this));
  ssp_client->start();
}

SSPCollege::CameraObject::~CameraObject()
{
  ssp_client->stop();
}

bool SSPCollege::CameraObject::GetTestStatus()
{
  return TestStatus;
}

void SSPCollege::CameraObject::on_264_callback(struct imf::SspH264Data * h264)
{
  if(RunTest)
    TestStatus=true;
  else
  funcHandle((const char*)h264->data,h264->len,h264->frm_no,userData);
}

void SSPCollege::CameraObject::StartShot()
{
  RunTest=false;
  auto res=client.Get("/ctrl/rec?action=start");
  if(res==nullptr) throw std::runtime_error("无法启动相机进入拍摄模式");
}

void SSPCollege::CameraObject::StopShot()
{
  auto res=client.Get("/ctrl/rec?action=stop");
  if(res==nullptr) throw std::runtime_error("相机无法停止拍摄");
}

void SSPCollege::CameraObject::on_audio_callback(struct imf::SspAudioData * audio)
{

}

void SSPCollege::CameraObject::on_meta_callback(struct imf::SspVideoMeta * v,struct imf::SspAudioMeta* a,struct imf::SspMeta * m)
{

}

void SSPCollege::CameraObject::on_disconnect_callback()
{

}
